#include "ColoredLines.h"
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>
#include <vtkLine.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkUnsignedCharArray.h>

ColoredLines::ColoredLines(QWidget *parent)
    : QMainWindow(parent)
{
    this->resize(600, 400);
    // Create the polydata where we will store all the geometric data
    vtkNew<vtkPolyData> linesPolyData;

    // Create three points
    double origin[3] = { 0.0, 0.0, 0.0 };
    double p0[3] = { 1.0, 0.0, 0.0 };
    double p1[3] = { 0.0, 1.0, 0.0 };

    // Create a vtkPoints container and store the points in it
    vtkNew<vtkPoints> pts;
    pts->InsertNextPoint(origin);
    pts->InsertNextPoint(p0);
    pts->InsertNextPoint(p1);

    // Add the points to the polydata container
    linesPolyData->SetPoints(pts);

    // Create the first line (between Origin and P0)
    vtkNew<vtkLine> line0;
    line0->GetPointIds()->SetId(
        0,
        0); // the second 0 is the index of the Origin in linesPolyData's points
    line0->GetPointIds()->SetId(
        1, 1); // the second 1 is the index of P0 in linesPolyData's points

    // Create the second line (between Origin and P1)
    vtkNew<vtkLine> line1;
    line1->GetPointIds()->SetId(
        0,
        0); // the second 0 is the index of the Origin in linesPolyData's points
    line1->GetPointIds()->SetId(
        1, 2); // 2 is the index of P1 in linesPolyData's points

    // Create a vtkCellArray container and store the lines in it
    vtkNew<vtkCellArray> lines;
    lines->InsertNextCell(line0);
    lines->InsertNextCell(line1);

    // Add the lines to the polydata container
    linesPolyData->SetLines(lines);

    vtkNew<vtkNamedColors> namedColors;

    // Create a vtkUnsignedCharArray container and store the colors in it
    vtkNew<vtkUnsignedCharArray> colors;
    colors->SetNumberOfComponents(3);
    colors->InsertNextTypedTuple(namedColors->GetColor3ub("Tomato").GetData());
    colors->InsertNextTypedTuple(namedColors->GetColor3ub("Mint").GetData());

    // Color the lines.
    // SetScalars() automatically associates the values in the data array passed
    // as parameter to the elements in the same indices of the cell data array on
    // which it is called. This means the first component (red) of the colors
    // array is matched with the first component of the cell array (line 0) and
    // the second component (green) of the colors array is matched with the second
    // component of the cell array (line 1)
    linesPolyData->GetCellData()->SetScalars(colors);

    // Setup the visualization pipeline
    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputData(linesPolyData);

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->SetLineWidth(4);

    vtkNew<vtkRenderer> renderer;
    renderer->AddActor(actor);
    renderer->SetBackground(namedColors->GetColor3d("SlateGray").GetData());
    vtkWidget = new QVTKOpenGLNativeWidget(this);
    vtkWidget->renderWindow()->AddRenderer(renderer);
    this->setCentralWidget(vtkWidget);
}
